module pipeline_control(
  input i_ex1_done,
  input i_ex3_update,
  input i_ex3_done,
  input i_fe1_valid,
  input i_de1_valid,
  input i_de2_valid,
  input i_ex1_valid,
  input i_ex2_valid,
  input i_ex3_valid,
  input i_wb_valid,
  input i_instr_ack,
  input i_irq,
  input i_irq_mask,
  output o_fe1_valid_next,
  output o_pc_we,
  output o_de1_ir_we,
  output o_de2_ir_we,
  output o_ex1_ir_we,
  output o_ex2_ir_we,
  output o_ex3_ir_we,
  output o_de2_ir_dsel
);

wire next_instr;
wire irq;

assign next_instr = ~i_fe1_valid & ~i_de1_valid & ~i_de2_valid & ~i_ex1_valid & ~i_ex2_valid & ~i_ex3_valid & ~i_wb_valid;
assign irq = i_irq & ~i_irq_mask;

assign o_fe1_valid_next = next_instr & ~irq;
assign o_pc_we = ~i_fe1_valid & ~i_de1_valid & ~i_de2_valid & ~i_ex1_valid & ~i_ex2_valid & ~i_ex3_valid & i_wb_valid;
assign o_de1_ir_we = i_ex3_update & i_ex3_done & i_ex1_done & i_instr_ack;
assign o_de2_ir_we = i_ex3_update & i_ex3_done & i_ex1_done;
assign o_ex1_ir_we = i_ex3_update & i_ex3_done;
assign o_ex2_ir_we = i_ex3_update & i_ex3_done;
assign o_ex3_ir_we = i_ex3_update;
assign o_de2_ir_dsel = next_instr & irq;

endmodule
